package com.sky.security.filter;


import com.alibaba.fastjson.JSON;
import com.sky.constant.JwtClaimsConstant;
import com.sky.exception.LoginFailedException;
import com.sky.properties.JwtProperties;
import com.sky.result.Result;
import com.sky.security.domain.LoginUser;
import com.sky.security.utils.WebUtils;
import com.sky.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Objects;

@Component
@Slf4j
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private JwtProperties jwtProperties;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        //这里没有token也放行 是因为这个拦截器是拦截了所有 没有放行登录接口
        // 这里过滤器先执行 还有一个自己搞的拦截器
        String token = request.getHeader(jwtProperties.getAdminTokenName());
        if (!StringUtils.hasText(token)) {
            //放行
            filterChain.doFilter(request, response);
            return;
        }
        String uri = request.getRequestURI();
        if ("/admin/employee/login".equals(uri)) {//对登录接口放行
            filterChain.doFilter(request, response);
            return;
        }

        //2、校验令牌
        try {
            Claims claims = JwtUtil.parseJWT(jwtProperties.getAdminSecretKey(), token);
            Long empId = Long.valueOf(claims.get(JwtClaimsConstant.EMP_ID).toString());
            //从redis中获取用户信息
            String redisKey = "login:" + empId;
            LoginUser loginUser = (LoginUser)redisTemplate.opsForValue().get(redisKey);
            if (Objects.isNull(loginUser)) {
                //throw new RuntimeException("用户未登录");
                throw new LoginFailedException("登录失败");
            }
            //存入SecurityContextHolder
            UsernamePasswordAuthenticationToken authenticationToken =
                    new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
            //放行
            filterChain.doFilter(request, response);
            return;
        } catch (Exception ex) {
            //4、不通过，响应401状态码
            //处理异常

            log.error("出错 不通过");
            response.setStatus(401);
            filterChain.doFilter(request,response);
        }
    }
}
